package com.fengwan.wastesort.ui.fragment

import android.Manifest
import android.app.Activity.RESULT_OK
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProviders
import com.baidu.aip.imageclassify.AipImageClassify
import com.fengwan.waste.util.createImageFile
import com.fengwan.wastesort.R
import com.fengwan.wastesort.constant.Constants
import com.fengwan.wastesort.model.BaiduClientErrorDescriptionKey
import com.fengwan.wastesort.model.BaiduClientErrorDescriptionSecretKey
import com.fengwan.wastesort.model.BaiduTokenModel
import com.fengwan.wastesort.net.HttpUtil
import com.fengwan.wastesort.utils.baiduai.Base64Util
import com.fengwan.wastesort.utils.baiduai.FileUtil
import com.google.android.material.snackbar.Snackbar
import com.tbruyelle.rxpermissions2.RxPermissions
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import com.xuexiang.xui.widget.dialog.strategy.impl.MaterialDialogStrategy
import io.reactivex.BackpressureStrategy
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.internal.operators.completable.CompletableToFlowable
import io.reactivex.rxkotlin.toFlowable
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.fragment_photograph.*
import okhttp3.MediaType
import okhttp3.ResponseBody
import retrofit2.http.Body
import top.zibin.luban.Luban
import top.zibin.luban.OnCompressListener
import java.io.File
import java.net.URLEncoder
import java.nio.ByteBuffer

class PhotographFragment : Fragment() {

    private val CAMERA_CODE = 0x001

    companion object {
        fun newInstance() = PhotographFragment()
    }

    private lateinit var viewModel: PhotographViewModel
    private val rxPermissions by lazy { RxPermissions(this) }
    private val api by lazy { HttpUtil.getInstance().getBaiduService() }
    private val compositeDisposable by lazy { CompositeDisposable() }

    private val options by lazy { hashMapOf<String, String>() }
    private val client by lazy {
        AipImageClassify(
            Constants.BUIDU_APP_ID,
            Constants.BUIDU_APP_KEY,
            Constants.BUIDU_APP_SECRET_KEY
        )
    }


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_photograph, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProviders.of(this).get(PhotographViewModel::class.java)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        options["baike_num"] = "10"
        tv_phone.setOnClickListener { v ->
            if (rxPermissions.isGranted(Manifest.permission.CAMERA)) {
//                startActivity(Intent(context, ShootingActivity::class.java))
                takePicture("photo", CAMERA_CODE)
            } else {
                rxPermissions
                    .request(Manifest.permission.CAMERA)
                    .subscribe {
                        if (it) {
//                            startActivity(Intent(context, ShootingActivity::class.java))
                            takePicture("photo", CAMERA_CODE)
                        } else {
                            Snackbar.make(v, "权限不足， 请重试!", Snackbar.LENGTH_LONG).show()
                        }
                    }
            }
        }

    }

    /**
     * 通过手机照相获取图片
     *
     * @param activity
     * @return 照相后图片的路径
     */
    lateinit var currentPhotoPath: String

    private fun takePicture(name: String, requestCode: Int) {
        compositeDisposable.add(io.reactivex.Observable.just(name)
            .map {
                val imageFile = File(name).createImageFile(context!!)
//                if (imageFile.exists()) {
//                    imageFile.deleteOnExit()
//                }
                return@map imageFile
            }
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
                if (it != null) {
                    currentPhotoPath = "${it.absolutePath}"
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, getUriForFile(it))
                }
                startActivityForResult(intent, requestCode)
            })
    }

    private fun getUriForFile(file: File?): Uri {
        if (context == null || file == null) {
            throw NullPointerException()
        }
        return if (Build.VERSION.SDK_INT >= 24) {
//            context?.applicationContext?.let {
//                FileProvider.getUriForFile(
//                    it,
//                    "com.fengwan.wastesort.fileprovider",
//                    file
//                )
//            }!!
            FileProvider.getUriForFile(context!!, "com.fengwan.wastesort.fileprovider", file)
        } else {
            Uri.fromFile(file)
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            CAMERA_CODE -> {
                if (RESULT_OK != resultCode) return

                baiduiApi()
            }
            else -> {
            }
        }

    }

    lateinit var token: String
    private fun baiduiApi() {
//        Luban.with(context)
//            .load(currentPhotoPath)
//            .ignoreBy(100)
//            .setCompressListener(object : OnCompressListener {
//                        override fun onSuccess(file: File?) {
//                            Log.d("Luban", "图片压缩成功！")
//                            Thread(Runnable { val res =
//                                client.advancedGeneral(FileUtil.readFileByBytes(file), options)
//                                Log.d("百度识图", res.toString())
//                            }).start()
//                        }
//
//                        override fun onError(e: Throwable?) {
//                            Log.d("Luban", "图片压缩失败！")
//                        }
//
//                        override fun onStart() {
//                            Log.d("Luban", "图片正在压缩!")
//                        }
//                    })
//            .launch()
//
        compositeDisposable.add(api.getAccessToken(Constants.BUIDU_APP_KEY, Constants.BUIDU_APP_SECRET_KEY)
            .subscribeOn(Schedulers.io())
            .flatMap {
                if (!it.error.isNullOrBlank()) {
                    return@flatMap error(it.error_description)
                } else {
                    token = it.access_token
                    return@flatMap Observable.just(currentPhotoPath).toFlowable(BackpressureStrategy.BUFFER)
                }
            }
            .flatMap {
                return@flatMap Luban.with(context)
                    .load(it)
                    .ignoreBy(100)
                    .setCompressListener(object : OnCompressListener {
                        override fun onSuccess(file: File?) {
                            Log.d("Luban", "图片压缩成功！")
                        }

                        override fun onError(e: Throwable?) {
                            Log.d("Luban", "图片压缩失败！")
                        }

                        override fun onStart() {
                            Log.d("Luban", "图片正在压缩!")
                        }
                    })
                    .get()
                    .toFlowable()
            }.flatMap {
                File(currentPhotoPath).apply {
                    if (exists() && isFile) {
                        if (delete()) {
                            Log.d("Image", "临时照片${name}删除成功")
                        }
                    }
                }
                Log.d("Image", "压缩后的图片大小为${it.length()}")
                Log.d("Image", "正在进行图片转Byte[]操作！")
                val imageData = FileUtil.readFileByBytes(it)
                Log.d("Image", "正在进行图片Base64编码！")
                val imageStr = Base64Util.encode(imageData)
                Log.d("Image", "正在上传图片进行识别！")
                return@flatMap api.imageClassify(token, 10, imageStr)
            }
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                Log.d("百度识图", it.toString())
            }, {
                when (it.message) {
                    BaiduClientErrorDescriptionKey -> {
                        Toast.makeText(context, "API Key不正确", Toast.LENGTH_LONG).show()
                    }
                    BaiduClientErrorDescriptionSecretKey -> {
                        Toast.makeText(context, "Secret Key不正确", Toast.LENGTH_LONG).show()
                    }
                    else -> {
                    }
                }
                it.printStackTrace()
            })
        )
    }

    override fun onDestroy() {
        super.onDestroy()
        compositeDisposable.clear()
    }

}